Conversation
There was a problem hiding this comment.
Hey - 我发现了两个问题,并给出了一些整体性的反馈:
- 临时解压目录
temp_dir.join("mxu_webview2_extract")是固定路径;建议改为每次运行唯一的目录(例如包含 PID 或随机后缀),以避免在多个实例并发运行时或之前的运行遗留目录时出现冲突或竞争条件。
给 AI Agent 的提示词
请根据本次代码审查中的评论进行修改:
## 总体说明
- 临时解压目录 `temp_dir.join("mxu_webview2_extract")` 是固定路径;建议改为每次运行唯一的目录(例如包含 PID 或随机后缀),以避免在多个实例并发运行时或之前的运行遗留目录时出现冲突或竞争条件。
## 单条评论
### Comment 1
<location> `src-tauri/src/webview2/install.rs:97-99` </location>
<code_context>
+}
+
+/// 解压 cab 文件到 WebView2 运行时目录
+fn extract_cab_to_runtime(cab_path: &std::path::Path, runtime_dir: &std::path::Path) -> Result<(), String> {
+ let temp_dir = std::env::temp_dir();
+ let extract_temp = temp_dir.join("mxu_webview2_extract");
+
+ let _ = std::fs::remove_dir_all(&extract_temp);
</code_context>
<issue_to_address>
**issue (bug_risk):** 使用固定的临时目录进行解压,在多实例情况下可能产生冲突。
解压路径始终是 `%TEMP%/mxu_webview2_extract`,并且在每次运行前都会被删除。如果多个实例并发运行,或者其他进程也在复用这个 helper,它们可能会互相删除或覆盖对方的临时目录,导致偶发失败或清理不完全。应为每次运行使用唯一的临时目录(例如基于 PID/时间戳/随机后缀,或使用类似 `tempfile` 的 API)以避免这些竞争问题。
</issue_to_address>
### Comment 2
<location> `src-tauri/src/webview2/install.rs:184-193` </location>
<code_context>
+ }
+
+ // 优先使用架构匹配的 cab
+ if let Some(cab_path) = matched {
+ let progress_dialog = CustomDialog::new_progress(
+ "正在解压 WebView2",
+ "检测到本地 WebView2 运行时 cab 文件,正在解压...",
+ );
+
+ let result = extract_cab_to_runtime(&cab_path, runtime_dir);
+
+ if let Some(pw) = progress_dialog {
+ pw.close();
+ }
+
+ if result.is_ok() {
+ let _ = std::fs::remove_file(&cab_path);
+ }
+ return Some(result);
+ }
+
</code_context>
<issue_to_address>
**issue:** 本地 cab 解压失败时,并不会像注释所说那样回退到在线下载。
`try_extract_local_cab` 的文档说明在本地 cab 不可用时应该“返回 None 继续下载”,但如果存在匹配的 cab 且 `extract_cab_to_runtime` 失败(例如 cab 损坏/不完整),当前分支会返回 `Some(Err(_))`。此时 `download_and_extract` 会直接退出,而不会尝试在线下载,因此一次错误的本地 cab 可能会长期阻塞后续恢复。建议在解压失败时:(1) 删除该 cab 文件;(2) 返回 `None` 以触发在线下载;(3) 仅在在线下载也失败时再向上抛出错误。
</issue_to_address>帮我变得更有用!请对每条评论点 👍 或 👎,我会根据你的反馈改进后续的代码审查。
Original comment in English
Hey - I've found 2 issues, and left some high level feedback:
- The temporary extraction directory
temp_dir.join("mxu_webview2_extract")is a fixed path; consider using a per-run unique directory (e.g., including PID or a random suffix) to avoid clashes or race conditions when multiple instances run concurrently or when a previous run left the directory behind.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The temporary extraction directory `temp_dir.join("mxu_webview2_extract")` is a fixed path; consider using a per-run unique directory (e.g., including PID or a random suffix) to avoid clashes or race conditions when multiple instances run concurrently or when a previous run left the directory behind.
## Individual Comments
### Comment 1
<location> `src-tauri/src/webview2/install.rs:97-99` </location>
<code_context>
+}
+
+/// 解压 cab 文件到 WebView2 运行时目录
+fn extract_cab_to_runtime(cab_path: &std::path::Path, runtime_dir: &std::path::Path) -> Result<(), String> {
+ let temp_dir = std::env::temp_dir();
+ let extract_temp = temp_dir.join("mxu_webview2_extract");
+
+ let _ = std::fs::remove_dir_all(&extract_temp);
</code_context>
<issue_to_address>
**issue (bug_risk):** Using a fixed temp directory for extraction can cause conflicts between multiple instances.
The extraction path is always `%TEMP%/mxu_webview2_extract`, which is deleted before each run. If multiple instances run concurrently or another process shares this helper, they could delete or overwrite each other’s temp directory, leading to intermittent failures or incomplete cleanup. Use a per-run unique temp directory (e.g., PID/timestamp/random suffix or a `tempfile`-style API) to avoid these races.
</issue_to_address>
### Comment 2
<location> `src-tauri/src/webview2/install.rs:184-193` </location>
<code_context>
+ }
+
+ // 优先使用架构匹配的 cab
+ if let Some(cab_path) = matched {
+ let progress_dialog = CustomDialog::new_progress(
+ "正在解压 WebView2",
+ "检测到本地 WebView2 运行时 cab 文件,正在解压...",
+ );
+
+ let result = extract_cab_to_runtime(&cab_path, runtime_dir);
+
+ if let Some(pw) = progress_dialog {
+ pw.close();
+ }
+
+ if result.is_ok() {
+ let _ = std::fs::remove_file(&cab_path);
+ }
+ return Some(result);
+ }
+
</code_context>
<issue_to_address>
**issue:** Local cab extraction failures do not fall back to online download as the comment suggests.
The doc for `try_extract_local_cab` says it should “返回 None 继续下载” when the local cab is unusable, but if a matching cab exists and `extract_cab_to_runtime` fails (e.g. corrupted/partial cab), this branch returns `Some(Err(_))`. `download_and_extract` then exits without trying the online download, so a single bad local cab can permanently block recovery. Consider, on extraction failure: (1) delete the cab, (2) return `None` to trigger the online download, and (3) only bubble up an error if the online download also fails.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Pull request overview
This pull request migrates WebView2 deployment from system-wide installation (Evergreen Bootstrapper) to a local fixed-version runtime approach. The new implementation downloads WebView2 Fixed Version Runtime as a CAB file from Microsoft's CDN, extracts it to a local webview2_runtime/ directory alongside the executable, and uses the WEBVIEW2_BROWSER_EXECUTABLE_FOLDER environment variable to direct Tauri to use this isolated runtime instead of system-wide installation.
Changes:
- Replaces system installation workflow with local CAB download and extraction using Windows' native
expand.exe - Implements local CAB file detection for offline/pre-downloaded runtimes with architecture validation
- Adds UI improvements including proper window sizing with
AdjustWindowRect, throttled progress updates (≥200ms) to prevent blocking, and correct process exit behavior when users close the progress dialog
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 11 comments.
| File | Description |
|---|---|
| src-tauri/src/webview2/install.rs | Core migration: replaced Evergreen Bootstrapper download/install with Fixed Version CAB download/extraction logic, local CAB detection, streaming download with throttled UI updates, and architecture-aware GUID selection |
| src-tauri/src/webview2/dialog.rs | Fixed window sizing calculation using AdjustWindowRect, added dialog_type tracking for correct WM_CLOSE handling (exit process for progress dialogs) |
| src-tauri/src/webview2/detection.rs | Formatting only: added blank line before function |
| src-tauri/src/main.rs | Added early detection and environment variable setup for existing webview2_runtime directory, skip ensure_webview2() call when local runtime already configured |
|
我草 这Copilot怎么找了这么多自己的毛病 |
- 改进架构不支持的错误信息,注明仅支持 x64/ARM64 - 递归复制时检查并跳过符号链接 - 添加 TOCTOU 竞态条件注释说明 - 删除/创建 runtime_dir 时改进文件锁错误提示 - 下载完成后 flush 文件缓冲 - HTTP 客户端显式设置 TLS 证书验证 - 添加 HTTP 整体超时 (600s) 防止无限挂起 - SendMessageW 安全性注释说明必须同步调用 - 验证 webview2_runtime 目录包含 msedgewebview2.exe Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@sourcery-ai review |
There was a problem hiding this comment.
Hey - 我发现了 1 个问题,并且给出了一些总体反馈:
extract_cab_to_runtime辅助函数假设expand.exe已经在 PATH 中,并且除了一个通用错误之外,不会检查或细化失败原因;建议显式地从System32解析该可执行文件,并在其缺失时给出更清晰的错误信息,以避免在环境配置有问题时出现令人困惑的失败。- 在
download_and_extract中,临时 cab 路径只是temp_dir.join(cab_name),因此应用的并发实例可能会争用同一个文件;在临时文件名中加入进程 ID 或随机后缀会让这一点更加健壮。
给 AI 代理的提示
Please address the comments from this code review:
## Overall Comments
- `extract_cab_to_runtime` 辅助函数假设 `expand.exe` 已经在 PATH 中,并且除了一个通用错误之外,不会检查或细化失败原因;建议显式地从 `System32` 解析该可执行文件,并在其缺失时给出更清晰的错误信息,以避免在环境配置有问题时出现令人困惑的失败。
- 在 `download_and_extract` 中,临时 cab 路径只是 `temp_dir.join(cab_name)`,因此应用的并发实例可能会争用同一个文件;在临时文件名中加入进程 ID 或随机后缀会让这一点更加健壮。
## Individual Comments
### Comment 1
<location> `src-tauri/src/webview2/install.rs:106-102` </location>
<code_context>
+fn extract_cab_to_runtime(cab_path: &std::path::Path, runtime_dir: &std::path::Path) -> Result<(), String> {
</code_context>
<issue_to_address>
**suggestion:** 考虑增强对 `expand.exe` 调用的健壮性,并处理 `expand.exe` 缺失或不在 PATH 中的情况。
当前实现依赖 `expand.exe` 在 PATH 中;在锁定或精简的 Windows 环境中它可能不存在,从而只会产生一个通用的“运行 expand.exe 失败”错误信息。
建议:
- 通过 `%SystemRoot%\System32\expand.exe`(例如使用 `GetSystemDirectoryW`)解析可执行文件,而不是依赖 PATH。
- 区分“找不到可执行文件”和“非零退出码”两种情况,这样错误信息可以清楚地表明何时是 `expand.exe` 本身不可用。
这将使 cab 解压失败对用户来说更容易诊断。
</issue_to_address>帮我变得更有用!请在每条评论上点击 👍 或 👎,我会根据反馈改进后续的评审。
Original comment in English
Hey - I've found 1 issue, and left some high level feedback:
- The
extract_cab_to_runtimehelper assumesexpand.exeis available on PATH and doesn’t exist or resolve failures beyond a generic error; consider resolving it explicitly fromSystem32and surfacing a clearer message when it’s missing to avoid confusing failures on misconfigured environments. - In
download_and_extract, the temporary cab path is justtemp_dir.join(cab_name), so concurrent instances of the app could contend for the same file; including the process ID or a random suffix in the temp filename would make this more robust.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The `extract_cab_to_runtime` helper assumes `expand.exe` is available on PATH and doesn’t exist or resolve failures beyond a generic error; consider resolving it explicitly from `System32` and surfacing a clearer message when it’s missing to avoid confusing failures on misconfigured environments.
- In `download_and_extract`, the temporary cab path is just `temp_dir.join(cab_name)`, so concurrent instances of the app could contend for the same file; including the process ID or a random suffix in the temp filename would make this more robust.
## Individual Comments
### Comment 1
<location> `src-tauri/src/webview2/install.rs:106-102` </location>
<code_context>
+fn extract_cab_to_runtime(cab_path: &std::path::Path, runtime_dir: &std::path::Path) -> Result<(), String> {
</code_context>
<issue_to_address>
**suggestion:** Consider hardening the `expand.exe` invocation and handling the case where `expand.exe` is missing or not on PATH.
This relies on `expand.exe` being on PATH; in locked-down or minimal Windows setups it may be missing, resulting in a generic “运行 expand.exe 失败” message.
I’d suggest:
- Resolving `%SystemRoot%\System32\expand.exe` (e.g., via `GetSystemDirectoryW`) instead of depending on PATH.
- Distinguishing between “executable not found” and a non‑zero exit code so the error clearly indicates when `expand.exe` itself is unavailable.
That will make cab extraction failures more diagnosable for users.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| CustomDialog::show_error( | ||
| "系统 WebView2 已被禁用", | ||
| &format!( | ||
| "检测到系统 WebView2 已被禁用:\r\n{}\r\n\r\n\ | ||
| 【什么是 WebView2?】\r\n\ | ||
| WebView2 是微软提供的网页渲染组件,本程序依赖它来\r\n\ | ||
| 显示界面。如果 WebView2 被禁用,程序将无法正常运行。\r\n\r\n\ | ||
| 【如何解决?】\r\n\ | ||
| 方法一:如果使用了 Edge Blocker 等工具\r\n\ | ||
| - 打开 Edge Blocker,点击\"Unblock\"解除禁用\r\n\ | ||
| - 或删除注册表中的 IFEO 拦截项\r\n\r\n\ | ||
| 方法二:修改组策略(需要管理员权限)\r\n\ | ||
| 1. 按 Win + R,输入 gpedit.msc\r\n\ | ||
| 2. 导航到:计算机配置 > 管理模板 > Microsoft Edge WebView2\r\n\ | ||
| 3. 将相关策略设置为\"未配置\"或\"已启用\"\r\n\r\n\ | ||
| 方法三:加入我们的 QQ 群,获取帮助和支持\r\n\ | ||
| - 群号可在我们的官网或文档底部找到\r\n\r\n\ | ||
| 点击确定后将尝试下载独立 WebView2 运行时以继续运行。\r\n\ | ||
| 若想恢复使用系统 WebView2,请手动删除 exe 目录下的 webview2_runtime 文件夹", | ||
| reason | ||
| ), | ||
| ); |
There was a problem hiding this comment.
此处新增/扩展了大量面向用户的提示文案(标题/正文均为硬编码字符串)。仓库规范要求“所有面向用户的文本必须定义在 src/i18n/locales/ 中”(见 AGENTS.md 3.2)。建议将这些提示文案迁移到统一的本地化资源(至少提供 zh-CN/en-US),并在 Rust 侧通过一套可复用的字符串表/桥接方式读取,避免后续无法维护多语言一致性。
- 改进架构不支持的错误信息,注明仅支持 x64/ARM64 - 递归复制时检查并跳过符号链接 - 添加 TOCTOU 竞态条件注释说明 - 删除/创建 runtime_dir 时改进文件锁错误提示 - 下载完成后 flush 文件缓冲 - HTTP 客户端显式设置 TLS 证书验证 - 添加 HTTP 整体超时 (600s) 防止无限挂起 - SendMessageW 安全性注释说明必须同步调用 - 验证 webview2_runtime 目录包含 msedgewebview2.exe - expand.exe 从 System32 解析并为下载临时文件添加 PID 前缀 - 从 %SystemRoot%\System32 解析 expand.exe 完整路径,不依赖 PATH - expand.exe 不存在时给出明确路径提示 - 下载的临时 cab 文件名添加 PID 前缀,避免并发实例冲突 - show_download_failed_dialog 不再默认回退 x64,架构不支持时展示专门提示 - 删除 runtime_dir 前通过 symlink_metadata 检查符号链接/重解析点,拒绝操作以防任意目录删除 - 新增 validate_runtime_dir 在设置环境变量前校验 msedgewebview2.exe 存在 - 下载临时 cab 路径已在上次提交中添加 PID 前缀 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
c4408b0 to
4c60ca1
Compare
怎么七点了写不动 description 了找 LLM 写了
WebView2 Fixed Version Runtime 支持
将 WebView2 从系统安装(Evergreen Bootstrapper)改为本地固定版本运行时(Fixed Version Runtime),下载后解压到 exe 同目录使用,不影响系统环境,且在 MXU 自更新后仍然生效。
主要变更
核心功能:本地 WebView2 运行时
触发逻辑
本地 cab 文件支持
下载体验优化
UI 修复
Summary by Sourcery
将 WebView2 集成方式从系统范围的 Evergreen 安装器切换为在可执行文件旁解压的本地固定版本运行时,并改进下载处理和对话框体验。
New Features:
webview2_runtime目录中运行。.cab文件,以便在离线或低网络环境中完成安装。Bug Fixes:
Enhancements:
AdjustWindowRect调整窗口大小以保证控件可见。Original summary in English
Summary by Sourcery
Switch WebView2 integration from system-wide Evergreen installer to a local fixed-version runtime unpacked alongside the executable, with improved download handling and dialogs.
New Features:
Bug Fixes:
Enhancements:
Original summary in English
Summary by Sourcery
将 WebView2 集成方式从系统范围的 Evergreen 安装器切换为在可执行文件旁解压的本地固定版本运行时,并改进下载处理和对话框体验。
New Features:
webview2_runtime目录中运行。.cab文件,以便在离线或低网络环境中完成安装。Bug Fixes:
Enhancements:
AdjustWindowRect调整窗口大小以保证控件可见。Original summary in English
Summary by Sourcery
Switch WebView2 integration from system-wide Evergreen installer to a local fixed-version runtime unpacked alongside the executable, with improved download handling and dialogs.
New Features:
Bug Fixes:
Enhancements: